#include "mkdelegates.h"
#include "mktablemodel.h"

#include "mkcore/mkcore.h"
#include "mkcore/mksettings.h"

#include <QComboBox>
#include <QSpinBox>
#include <QDateEdit>

#include <QDebug>



MKFactoryDelegate::MKFactoryDelegate(QObject *parent) : QObject(parent)
{

}

QItemDelegate *MKFactoryDelegate::delegateFromType(quint8 typeId)
{
	switch (typeId)
	{
		case C_Date: return new MKDateDelegate;
		case C_Type :return new MKTypeDelegate;
		case C_Category :return new MKCategoryDelegate;
		default: return new QItemDelegate;
	}
}

///-------------------------------------------------------------------------------------------------------------------------------

MKTypeDelegate::MKTypeDelegate(QObject *parent) : QItemDelegate(parent)
{
}

QWidget *MKTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const
{
	QComboBox *pComboBox = new QComboBox(parent);

	QList<QPair<quint8, QString> > typesParameters = MKCore::instance()->settings()->typesParameters();
	QListIterator<QPair<quint8, QString> > i(typesParameters);
	while(i.hasNext())
	{
		QPair<quint8, QString> typeParameters = i.next();
		pComboBox->addItem(typeParameters.second, typeParameters.first);
	}

	return pComboBox;
}

void MKTypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
	QComboBox *pComboBox = static_cast<QComboBox*>(editor);
	if (!pComboBox)
	{
		qDebug() << Q_FUNC_INFO
				 << "error casting for QComboBox from editor = " << editor;
		return;
	}

	quint8 typeId = static_cast<quint8>(index.model()->data(index, Qt::EditRole).toUInt());

	int indexComboBox = 0;
	while (indexComboBox < pComboBox->count())
	{
		quint8 itemTypeId = static_cast<quint8>(pComboBox->itemData(indexComboBox, Qt::UserRole).toUInt());
		if (itemTypeId == typeId)
		{
			break;
		}
		++indexComboBox;
	}

	pComboBox->setCurrentIndex(indexComboBox);
}

void MKTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
	QComboBox *pComboBox = static_cast<QComboBox*>(editor);
	if (!pComboBox)
	{
		qDebug() << Q_FUNC_INFO
				 << "error casting for QComboBox from editor = " << editor;
		return;
	}

	int currentIndex = pComboBox->currentIndex();
	model->setData(index, pComboBox->itemData(currentIndex), Qt::EditRole);
}

void MKTypeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const
{
	editor->setGeometry(option.rect);
}

///---------------------------------------------------------------------------------------------------------------------

MKCategoryDelegate::MKCategoryDelegate(QObject *parent) : QItemDelegate(parent)
{

}

QWidget *MKCategoryDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
{
	QComboBox *pComboBox = new QComboBox(parent);

	return pComboBox;
}

void MKCategoryDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
	QComboBox *pComboBox = static_cast<QComboBox*>(editor);
	if (!pComboBox)
	{
		qDebug() << Q_FUNC_INFO
				 << "error casting for QComboBox from editor = " << editor;
		return;
	}

	QModelIndex typeIndex = index.model()->index(index.row(), C_Type);
	quint8 typeId = static_cast<quint8>(typeIndex.model()->data(typeIndex, Qt::EditRole).toUInt());

	pComboBox->clear();
	QList<QPair<quint8, QString> > typeCategoriesParameters = MKCore::instance()->settings()->typeCategoriesParameters(typeId);
	QListIterator<QPair<quint8, QString> > i(typeCategoriesParameters);
	while(i.hasNext())
	{
		QPair<quint8, QString> typeCategoriesParameters = i.next();
		pComboBox->addItem(typeCategoriesParameters.second, typeCategoriesParameters.first);
	}

	quint8 categoryId = static_cast<quint8>(index.model()->data(index, Qt::EditRole).toUInt());

	int indexComboBox = 0;
	while (indexComboBox < pComboBox->count())
	{
		quint8 itemCategoryId = static_cast<quint8>(pComboBox->itemData(indexComboBox, Qt::UserRole).toUInt());
		if (itemCategoryId == categoryId)
		{
			break;
		}
		++indexComboBox;
	}

	pComboBox->setCurrentIndex(indexComboBox);
}

void MKCategoryDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
	QComboBox *pComboBox = static_cast<QComboBox*>(editor);
	if (!pComboBox)
	{
		qDebug() << Q_FUNC_INFO
				 << "error casting for QComboBox from editor = " << editor;
		return;
	}

	int currentIndex = pComboBox->currentIndex();
	model->setData(index, pComboBox->itemData(currentIndex), Qt::EditRole);
}

void MKCategoryDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
{
	editor->setGeometry(option.rect);
}


///---------------------------------------------------------------------------------------------------------------------


MKDateDelegate::MKDateDelegate(QObject *parent) :QItemDelegate(parent)
{

}

QWidget *MKDateDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
{
	QDateEdit *pDateEdit = new QDateEdit(parent);
	pDateEdit->setDisplayFormat("dd.MM.yyyy");
	return pDateEdit;
}

void MKDateDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
	QDateEdit *pDateEdit = static_cast<QDateEdit*>(editor);
	if (!pDateEdit)
	{
		qDebug() << Q_FUNC_INFO
				 << "error casting for QDateEdit from editor = " << editor;
		return;
	}

	quint32 dateTime_t = static_cast<quint32>(index.data(Qt::EditRole).toUInt());
	pDateEdit->setDateTime(QDateTime::fromTime_t(dateTime_t));
}

void MKDateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
	QDateEdit *pDateEdit = static_cast<QDateEdit*>(editor);
	if (!pDateEdit)
	{
		qDebug() << Q_FUNC_INFO
				 << "error casting for QDateEdit from editor = " << editor;
		return;
	}

	quint32 dateTime_t = static_cast<quint32>(pDateEdit->dateTime().toTime_t());
	model->setData(index, dateTime_t, Qt::EditRole);
}

void MKDateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
{
	editor->setGeometry(option.rect);
}
